/***********************************************************
 * author: wuzhong
 * create: 2022-09-05
 * email：419479707@qq.com
 * source:
 * board:esp8266 core for arduino v3.0.2
 ***********************************************************/

#include "Helper.h"
#include <DHT.h>      //调用dht11驱动库
#define DHTPIN 2     //说明数据接口为8266开发板的D4口，也可以写为#define DHTPIN 2既8266芯片的IO口2
#define DHTTYPE DHT11 //说明使用的模块是DHT11
DHT dht(DHTPIN, DHTTYPE);

long lastMqttConn;     // 上次mqtt连接时间
long lastDataMonitor;  // 上次定时发布温湿度数据

/**
 * 启动
 */
void setup()
{
  //开始测量
  dht.begin();
  //打开串行端口：
  Serial.begin(115200);
  printMsg("bihua smart device starting...");
  createAPAndWebServer();
  //connectWifi();
  //connectMqtt();
}
/**
 * 循环执行
 */
void loop()
{
    // 检查http服务器访问
  server.handleClient();
  // Wifi掉线重连
  if (wifiOpen == 1 && WiFi.status() != WL_CONNECTED)
  {
    connectWifi();
  }
  // 非阻塞Mqtt重连，间隔30秒
  if (mqttOpen == 1 && WiFi.status() == WL_CONNECTED)
  {
    long now = millis();
    if (!mqttClient.connected())
    {
      if (now - lastMqttConn > 30000)
      {
        lastMqttConn = now;
        connectMqtt();
      }
    }
    else
    {
      mqttClient.loop();
    }
  }
  // 非阻塞定时上报，测试用，60秒发布一次
  if (mqttOpen == 1 && WiFi.status() == WL_CONNECTED)
  {
    long now = millis();
    if (now - lastDataMonitor > 1*60*1000)
    {
      lastDataMonitor = now;
      printMsg("执行定时上报");
      getAndSendTemperatureAndHumidityData();
    }
  }
}

void getAndSendTemperatureAndHumidityData()
{
  printMsg("Collecting temperature data.");
  // Reading temperature or humidity takes about 250 milliseconds!
  float humidity = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float temperature = dht.readTemperature();
  // Check if any reads failed and exit early (to try again).
  if (isnan(humidity) || isnan(temperature))
  {
    printMsg("Failed to read from DHT11!");
    return;
  }
  StaticJsonDocument<1024> docDevices;
  JsonArray arrayDevices = docDevices.createNestedArray("devices");

  StaticJsonDocument<200> docDevice;
  JsonObject rootDevice = docDevice.to<JsonObject>();
  rootDevice["deviceId"] = deviceIdentification;

  StaticJsonDocument<1024> docServices;
  JsonArray rootServices = docServices.to<JsonArray>();
  StaticJsonDocument<200> docService;
  JsonObject rootService = docService.to<JsonObject>();
  rootService["serviceId"] = "server1";  
  StaticJsonDocument<200> docData;
  JsonObject objTmeperature = docData.to<JsonObject>();
  objTmeperature["humidity"] = (String)(humidity);
  objTmeperature["temperature"] = (String)(temperature);
  rootService["data"] = objTmeperature;  
  rootService["eventTime"] = "20230719062112";  
  rootServices.add(docService);
  
  rootDevice["services"] = rootServices;
  arrayDevices.add(rootDevice);


  serializeJson(docDevices, Serial);
  String output;
  serializeJson(docDevices, output);
  printMsg("定时上报数据：");
  Serial.print(output);
  //String topic = "/v1/devices/bihua_t_h/datas";
  mqttClient.publish(deviceTopic, output.c_str());
}
